<?php

use Illuminate\Database\Capsule\Manager as DB;

class RankinglistdataController extends CoreController
{
    public function init()
    {
        if (!$this->isCli()) {
            throw new Exception("Go to cli please!", '303');
        }
        parent::init();
    }

    public function adddateAction()
    {
        $allow_mode = [
            'today',
            'thisweek',
            'yesterday',
            'lastweek',
            'thismonth',
            'lastmonth'
        ];
        $mode = $this->get('mode');
        if (!in_array($mode, $allow_mode)){
            exit('非法时间');
        }
        if($this->getData(['mode'=>$mode])){
            echo '数据获取成功！';
        }else{
            echo '数据获取失败';
        }
    }

    private function getData($args = [])
    {
        $order_query = DB::table('order', 'orders')
            ->leftJoin('order_item as goods',function ($join){
                $join->on('orders.id', '=', 'goods.order_id')
                ->where('goods.refund_status', '>', 1);
            })
            ->where('orders.status', '>', 0)
            ->whereNull('orders.deleted_at')
            ->Select(['orders.id', 'orders.member_id', 'orders.customer_id', 'orders.pay_fee'])
            ->addselect(DB::Raw("IFNULL(SUM(`{$this->config->database->prefix}goods`.`refund_fee`), 0) AS `total_order_refund`"))
            ->groupBy('orders.id');
        if (isset($args['mode'])){
            $startOn = '';
            $endOn = '';
            $operator = 'between';
            switch ($args['mode']){
                case 'today':
                    $startOn = carbon()->today()->format('Y-m-d');
                    $operator = 'eq';
                    break;
                case 'thisweek':
                    $startOn = carbon()->startOfWeek()->format('Y-m-d');
                    break;
                case 'yesterday':
                    $startOn = carbon()->yesterday()->format('Y-m-d');
                    $operator = 'eq';
                    break;
                case 'lastweek':
                    $startOn = carbon()->subDays(7)->startOfWeek()->format('Y-m-d');
                    $endOn = carbon()->subDays(7)->endOfWeek()->format('Y-m-d');
                    break;
                case 'thismonth':
                    $startOn = carbon()->startOfMonth()->format('Y-m-d');
                    break;
                case 'lastmonth':
                    $startOn = carbon()->subMonth()->startOfMonth()->format('Y-m-d');
                    $endOn =  carbon()->subMonth()->endOfMonth()->format('Y-m-d');
                    break;
            }
            if(!empty($startOn)){
                if($operator === 'between'){
                    $order_query = $order_query->whereDate('orders.created_at', '>=', $startOn);
                }else{
                    $order_query = $order_query->whereDate('orders.created_at', '=', $startOn);
                }
            }
            if(!empty($endOn)){
                $order_query = $order_query->whereDate('orders.created_at', '<=', $endOn);
            }
        }
        $order_sql = $order_query->toSql();
        $ok_order_query = DB::table(DB::Raw("($order_sql) as ok_order"))->mergeBindings($order_query);
        $ok_order_query = $ok_order_query->selectRaw('IF( customer_id > 0, customer_id, member_id ) order_user_id')
            ->addSelect(DB::Raw('GROUP_CONCAT( id ) order_ids'))
            ->addSelect(DB::Raw('COUNT(id) order_numbers'))
            ->addSelect(DB::Raw('SUM( pay_fee ) total_payed'))
            ->addSelect(DB::Raw('SUM( total_order_refund ) total_refund'))
            ->addSelect(DB::Raw('(SUM( pay_fee ) - SUM( total_order_refund )) total_money'))
            ->groupBy('order_user_id');
        $ok_order_sql = $ok_order_query->toSql();
        $now_order_query = DB::table(DB::Raw("($ok_order_sql) as {$this->config->database->prefix}now_order"))->mergeBindings($ok_order_query);
        $now_order_query = $now_order_query
            ->leftJoin('member', 'member.id', '=', 'now_order.order_user_id')
            ->select(['now_order.*', 'member.nickname', 'member.parent_member_id']);
        $datas = $now_order_query->get();
        if($datas){
            return $this->formatData($datas, $args['mode']);
        }else{
            return false;
        }
    }

    private function formatData($datas = [], $mode = '')
    {
        if(count($datas)){
            $insertData = [];
            $created_at = timestamp();
            $mode_start_id = 1;
            switch ($mode){
                case 'thisweek':
                    $mode_start_id = 10000000;
                    break;
                case 'yesterday':
                    $mode_start_id = 20000000;
                    break;
                case 'lastweek':
                    $mode_start_id = 30000000;
                    break;
                case 'thismonth':
                    $mode_start_id = 40000000;
                    break;
                case 'lastmonth':
                    $mode_start_id = 50000000;
                    break;
            }
            foreach ($datas as $row){
                if(bccomp($row->total_money, 0, 2) <= 0){
                    continue;
                }
                $new_row = [
                    'mode' => $mode,
                    'member_id' => $row->order_user_id,
                    'nickname'=>$row->nickname,
                    'consume'=>$row->total_money,
                    'order_num' => $row->order_numbers,
                    'created_at' => $created_at
                ];
                if($row->parent_member_id){
                    if(isset($insertData[$row->parent_member_id])){
                        $insertData[$row->parent_member_id]['consume'] = bcadd($insertData[$row->parent_member_id]['consume'], $row->total_money);
                        $insertData[$row->parent_member_id]['order_num'] += $row->order_numbers;
                    }else{
                        $insertData[$row->parent_member_id] = $new_row;
                        $insertData[$row->parent_member_id]['id'] = $mode_start_id;
                        $insertData[$row->parent_member_id]['member_id'] = $row->parent_member_id;
                        $insertData[$row->parent_member_id]['nickname'] = $this->getMemberName($row->parent_member_id);
                        $mode_start_id ++;
                    }
                }
                if(isset($insertData[$row->order_user_id])){
                    $insertData[$row->order_user_id]['consume'] = bcadd($insertData[$row->order_user_id]['consume'], $row->total_money);
                    $insertData[$row->order_user_id]['order_num'] += $row->order_numbers;
                }else{
                    $insertData[$row->order_user_id] = $new_row;
                    $insertData[$row->order_user_id]['id'] = $mode_start_id;
                    $mode_start_id ++;
                }
                unset($new_row);
            }
            unset($row);
            try {
                //删除旧数据，添加新数据，此方法，速度快，但是ID字段使用浪费
                DB::table('ranking_list')->where('mode', $mode)->delete();
                DB::table('ranking_list')->insert($insertData);
                unset($insertData, $created_at, $mode, $datas);
                return true;
            }catch (Exception $exception){
                return false;
            }
        }else{
            return false;
        }
    }

    private function getMemberName($id)
    {
       if(is_numeric($id) && $id>0){
           try {
               $member = DB::table('member')->find($id);
               if($member){
                   return $member->nickname;
               }else{
                   return 'no member';
               }
           }catch (Exception $exception){
               return 'db error';
           }
       }else{
           return 'ID error';
       }
    }
}